#ifdef  HAVE_CONFIG_H
#include  <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#define MAPSIZE 100
struct map  //存储资源表结构
{
    int m_addr;
    int m_size;
};
struct map map[MAPSIZE];  //存储资源表

//BF存储分配函数
int BF_malloc(struct map *mp,int size)  
{
    register int a,s;
    register struct map *bp,*bpp;

    for(bp = mp; bp->m_size; bp++)
    {
       if (bp->m_size >= size)//代表能够满足需求
        {
            a = bp->m_addr;
            s = bp->m_size;
            for(bpp = bp; bpp->m_size; bpp++)//从剩下的存储资源块中寻找
            {   //最佳适应
                if(bpp->m_size >= size && bpp->m_size < s)//要求能满足需求但是又空间比当前的小（最最小能满足）
                {
                    a = bpp->m_addr;
                    s = bpp->m_size;
                    bp = bpp;
                }
            }
            //执行分配地址空间
            bp->m_addr += size;
            if ((bp->m_size -= size) == 0)//更新内存长度
                //若当前内存块被完全分配
                do
                {
                    bp++;
                    (bp-1)->m_addr = bp->m_addr;//更新起始地址
                }
                while((bp-1)->m_size = bp->m_size);
            return(a);
        }
    }
    return(-1);
}

//WF存储分配函数
int WF_malloc(struct map *mp,int size) 
{
    register int a,s;
    register struct map *bp,*bpp;

    for(bp = mp; bp->m_size; bp++)
    {
        if (bp->m_size >= size)//代表能够满足需求
        {
            a = bp->m_addr;
            s = bp->m_size;
            for(bpp = bp; bpp->m_size; bpp++) //从剩下的存储资源块中寻找
            {   //最坏适应
                if(bpp->m_size > s) //要求能满足需求但是又空间比当前的大（求最大能满足）
                {
                    a = bpp->m_addr;
                    s = bpp->m_size;
                    bp = bpp;
                }
            }
            //执行分配地址空间
            bp->m_addr += size;
            if ((bp->m_size -=size) == 0)
                //若当前内存块被完全分配
                do
                {
                    bp++;
                    (bp-1)->m_addr = bp->m_addr;//更新起始地址
                }
                while((bp-1)->m_size = bp->m_size);
            return(a);
        }
    }
    return(-1);
}

//存储释放函数
void mfree(struct map *mp,int aa,int size) 
{
    register struct map *bp;
    register int t;
    register int a;

    a = aa;
    for(bp = mp; bp->m_addr<=a && bp->m_size != 0; bp++);
    if(bp>mp && (bp-1)->m_addr+(bp-1)->m_size==a)
    {   //与前合并
        (bp-1)->m_size += size;
        if (a+size == bp->m_addr)
        {   //前后合并
            (bp-1)->m_size += bp->m_size;
            while (bp->m_size)
            {
                bp++;
                (bp-1)->m_addr = bp->m_addr;
                (bp-1)->m_size = bp->m_size;
            }
        }
    }
    else
    {
         if (a+size == bp->m_addr && bp->m_size)
         {   //与后合并
              bp->m_addr -= size;
              bp->m_size += size;
         }
         else if (size)
              do
              {   //无合并
                   t = bp->m_addr;
                   bp->m_addr = a;
                   a = t;
                   t = bp->m_size;
                   bp->m_size = size;
                   bp++;
              }
              while (size = t);
    }
}

void init()
{
    struct map *bp;
    int addr,size;
    int i=0;
    bp=map;
    printf("Please input starting addr and total size:");
    scanf("%d,%d",&addr,&size);
    getchar(); //吸收换行（多加的代码）
    bp->m_addr=addr;
    bp->m_size=size;
    (++bp)->m_size=0;  //表尾
}

void show_map()
{
     int i=0;
     //system("clear");  //清屏 （原本没注释，现在注释掉了）
     struct map *bp;
     bp=map;
     printf("\nCurrent memory map...\n");
     printf("Address\t\tSize\n");
     while(bp->m_size!=0)
     {
        printf("<%d\t\t%d>\n",bp->m_addr,bp->m_size);
        bp++;
     }
     printf("\n");
}

int main()
{
    int a,s;
    // int c;//这样定义是不对滴！
    char c;//这样定义才对！
    int i;
    init();
    printf("Please input, b for BF, w for WF:");
    scanf("%c",&c);
    printf("\n我的选择是：%c\n",c);//输出下试试看看有没有正确读入c
    getchar(); //吸收换行（多加的代码）
    do
    {
        show_map(); //显示存储资源表

        printf("Please input,1 for request,2 for release,0 for exit:");
        scanf("%d",&i); //这里改正过来了，参考代码写的是&c而不是&i
        getchar(); //吸收换行（多加的代码）
        switch(i)
        {
            // request
            case 1:
                printf("Please input size:");
                scanf("%d", &s);
                getchar(); //吸收换行（多加的代码）
                if(c=='b')  //BF
                    {
                        printf("我现在所使用的算法是BF算法\n");
                        a=BF_malloc(map,s);
                    }
                else  //WF
                    {
                        printf("我现在所使用的算法是WF算法\n");
                        a=WF_malloc(map,s);
                    }
                if(a==-1)
                    printf("request can't be satisfied\n");
                else
                    printf("alloc memory at address:%d,size:%d\n",a,s);
                break;
            // release
            case 2:
                printf("Please input addr and size:");
                scanf("%d,%d",&a,&s);
                getchar(); //吸收换行（多加的代码）
                mfree(map,a,s);
                break;
            // exit
            case 0:
                exit(0);
        }
    }
    while(1);
}


/*
* 编译：gcc resource_manager.c -o resource_manager.out
* 运行：./resource_manager.out
*/